﻿// MMPlayer.cpp: 定义应用程序的入口点。
//
#include <thread>
#include <chrono>
#include <vector>
#include "MMThread/MMThread.h"
#include "MMAV/MMAV.h"
#include "MMQueue/MMQueue.h"


int main()
{
	// 实际上存放的AVPacket的指针	
	MMQueue<MMAVPacket> packetQueue;
	MMAVReader reader;
	int ret = reader.Open("D:/All Videos/testVideos/demo_1/newvideo.mp4");
	if (ret)
	{
		printf("File to open file!!!\n");
		return -1;
	}

	int vedioStreamIndex = reader.GetVideoStreamIndex();
	int audioStreamIndex = reader.GetAudioStreamIndex();
	printf("VedeoStreamIndex: %d\n", vedioStreamIndex);
	printf("AudioStreamIndex: %d\n", audioStreamIndex);

	std::vector<MMAVDecoder*> decoderList;

	int streamCount = reader.GetStreamCount();
	for (int i = 0; i < streamCount; i++)
	{
		// 获取流，存放在avStream
		MMAVStream avStream;
		reader.GetStream(&avStream, i);
		// 把流的索引打印出来
		printf("StreamIndex: %d\n", avStream.streamIndex);
		
		//初始化解码器
		MMAVDecoder* decoder = new MMAVDecoder();
		ret = decoder->Init(&avStream);
		if (ret)
		{
			printf("Init decoder fail ret : %d", ret);
		}
		// 把这些解码器存放在容器里，方便之后调用
		decoderList.push_back(decoder);
	}

	FILE* f = fopen("D:/All Videos/testVideos/demo_1/newvideo.yuv", "wb");

    // 开始读流
	while (1)
	{
		MMAVPacket* pkt = new MMAVPacket();
		ret = reader.Read(pkt);
		if (ret)
		{
			break;
		}
		
		packetQueue.Push(pkt);

		// 区分哪个流用哪个解码器
		int streamIndex = pkt->GetIndex();
		MMAVDecoder* decoder = decoderList[streamIndex];
		
		ret = decoder->SendPacket(pkt);
		if (ret)
		{
			continue;
		}

		while (1)
		{
			MMAVFrame frame;
			ret = decoder->RecvFrame(&frame);
			if (ret)
			{
				break;
			}

			// Recv Success
			if (streamIndex == vedioStreamIndex)
			{
				frame.VideoPrint();

				int width = frame.GetW();
				int height = frame.GetH();

				unsigned char* y = (unsigned char*)malloc(width * height);
				unsigned char* u = (unsigned char*)malloc(width / 2 * height / 2);
				unsigned char* v = (unsigned char*)malloc(width / 2 * height / 2);

				frame.GetY(y);
				frame.GetU(u);
				frame.GetV(v);

				// 将YUV的数据写入文件中
				fwrite(y, width * height, 1, f);
				fwrite(u, width / 2 * height / 2, 1, f);
				fwrite(v, width / 2 * height / 2, 1, f);


				free(y);
				free(u);
				free(v);
			}
			if (streamIndex == vedioStreamIndex)
			{
				//frame.AudeoPrint();
			}
			
		}
	}

	for (int i = 0; i < decoderList.size(); i++)
	{
		MMAVDecoder* decoder = decoderList[i];
		ret = decoder->SendPacket(nullptr);

		while (1)
		{
			MMAVFrame frame;
			ret = decoder->RecvFrame(&frame);
			if (ret)
			{
				break;
			}
		}
	}

	while (packetQueue.Size() > 0)
	{
		MMAVPacket* pkt = nullptr;
		packetQueue.Pop(&pkt);

		printf("Packet Size(): %d\n", packetQueue.Size());

		if (pkt != nullptr)
		{
			delete pkt;
		}
	}


	// 释放创建内存
	reader.CLose();

	for (int i = 0; i < decoderList.size(); i++)
	{
		MMAVDecoder* decoder = decoderList[i];
		decoder->Close();
		delete decoder;	
	}

	fclose(f);
	return 0;
}
